package com.dycong.common.threadUtil.ifun;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Logger;

/**
 * TODO 琦哥表数据迁移-->threadPool,lambda,LinkedBlockingQueue,JDBC
 * Created by dycong on 16/02/2017.
 */
public class DataTransfer {

    Logger log=Logger.getLogger(DataTransfer.class.getSimpleName());

    static Properties props;
    static OrignalBaseDao orignalBaseDao;
    static int pageSize=1000;

    static int maxSqlThread=40;

    static {
        props=new Properties();
        try {
            String path=DataTransfer.class.getProtectionDomain().getCodeSource().getLocation().getFile();
            File settingFile=Paths.get(new File(path).getParent(),"/settings.properties").toFile();
            if (settingFile.exists()){
                props.load(new FileInputStream(settingFile));
            }else{
                System.out.println("配置文件：");
                System.out.println(settingFile);
                System.out.println("不存在,请复制portal环境配置到该位置,再启用程序");
                errorConfirm(true);
            }


        } catch (IOException e) {
            e.printStackTrace();
        }
        orignalBaseDao=new OrignalBaseDao(
                props.getProperty("jdbc.driverClassName"),
                props.getProperty("jdbc.url"), props.getProperty("jdbc.username"), props.getProperty("jdbc.password")

        );

        System.out.println("------  ");

    }

    static ExecutorService threadPoolComponent=Executors.newFixedThreadPool(30);

    static ExecutorService threadPoolComponent2;

    static BlockingQueue<String> sqlQueue = new LinkedBlockingQueue();
    static BlockingQueue<Integer> pageQueue = new LinkedBlockingQueue();

    static String[] deleteSql=new String[]{
            "delete  from  n_order%s where order_id  in (%s);",
            "delete  from  n_order_pay_refund%s where order_number in (%s);",
            "delete  from  t_n_voucher%s where order_number in (%s);",
            "delete  from  n_order_product%s where order_number  in (%s);",
            "delete  from  n_ship_feedback%s where order_id  in (%s);",
            "delete  from  n_order_post_info%s where order_number  in (%s);",
    };


    public static void main(String[] args) {
        SimplePage page1=new SimplePage(0,pageSize,630453);
        int totalpageCount1=page1.getTotalPage();
        System.out.println(totalpageCount1);
        //System.exit(0);


        long beginTime=System.currentTimeMillis();
        if (args!=null && args.length>0){
            maxSqlThread=Integer.valueOf(args[0]);
            if (maxSqlThread<=0){
                System.out.println("sql执行线程数,必须大于 0,建议 30 - 50 ");
                errorConfirm(true);
            }

            if (args.length>1){
                pageSize=Integer.valueOf(args[1]);
                if (pageSize<=0){
                    System.out.println("每次批量删除订单数错误,必须大于 0,建议 1000 ");
                    errorConfirm(true);
                }
            }
        }else{
            System.out.println("参数提示：%1 sql任务执行线程数 默认 10,%2 一次删除多少订单，默认："+pageSize);
            errorConfirm(false);
        }
        threadPoolComponent2=Executors.newFixedThreadPool(30);
        int size=getOrderTotalSize();
        SimplePage page=new SimplePage(0,pageSize,size);
        int totalpageCount=page.getTotalPage();
        for (int i = 0; i <totalpageCount; i++) {
            pageQueue.add(i);
        }
        for (int k = 0; k < 13; k++) {
            threadPoolComponent2.execute(()->{
                Connection connection=orignalBaseDao.getConnection();
                while (!pageQueue.isEmpty()){
                    int i= -1;
                    try {
                        i = pageQueue.take().intValue();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (i>-1){
                        int start=(i==0)?0:i*pageSize;
                        int end=pageSize;
                        try {
                            long startTime=System.currentTimeMillis();
                            List<Map<String,String>> list=orignalBaseDao.getMapsList(connection,"select order_id from n_order limit "+start+","+end,false);
                            List<String> lines=new ArrayList<>();
                            StringBuffer ids=new StringBuffer();
                            for (int j = 0; j < list.size(); j++) {
                                ids.append("'").append(list.get(j).get("order_id")).append("',");
                            }
                            ids=ids.delete(ids.length()-1,ids.length());
                            for (int j = 0; j < deleteSql.length; j++) {
                                String sql=String.format(deleteSql[j],"_2016",ids.toString());
//                        lines.add(sql);
                                sqlQueue.add(sql);
                                //int count=orignalBaseDao.execute(connection,sql);
                                //System.out.println("sql:{} count:{}",sql,count);
                            }
                            lines.add("\n\n");

                            long endTime=System.currentTimeMillis();
                            System.out.println("totalCount:"+size+",pageCount"+totalpageCount+",page:"+i+" ," +
                                    "costTime:"+(endTime-startTime)+" ms,totalCost:"+(endTime-beginTime)+"ms");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }
        for (int i = 0; i < maxSqlThread; i++) {
            threadPoolComponent.submit(()->{
                Connection connection=orignalBaseDao.getConnection();
                boolean conti=true;
                while (conti){
                    try {
                        if (!sqlQueue.isEmpty()){
                            String sql=sqlQueue.take();
                            long start=System.currentTimeMillis();
                            try {
                                orignalBaseDao.execute(connection,sql);
                                System.out.println(Thread.currentThread().getName()+" execute sql..   ");
                            }catch (Exception e){
                                System.out.println(Thread.currentThread().getName()+" execute sql.."+sql+" "+e.getMessage());
                            }
                            System.out.println("cost time:"+(System.currentTimeMillis()-start)+"ms");
                        }else{
                            Thread.sleep(1000);
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            });
        }

    }

    public static int getOrderTotalSize(){

        try {
            List<Map<String,String>> list= orignalBaseDao.getMapsList("select count(*) size from n_order;",true);
            Object o=list.get(0).get("size");
           return ((Long)o).intValue();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static void errorConfirm(boolean exit){
        if (exit){
            System.out.println("回车后退出程序..");
        }else{
            System.out.println("回车后继续任务..");
        }
        try {
            System.in.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (exit)
            System.exit(0);
    }

}
